using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Text;
using System.Windows.Forms;

namespace IUPUI.StellarResults.Client.UIElements
{
	/// <summary>
	/// A view of <see cref="Reading"/>s from an <see cref="Observatory"/>.
	/// </summary>
	public partial class ReadingsControl : UserControl
	{
		#region Private Properties
		private Observatory m_Observatory = null;
		private bool m_WriteNonVisibleObjects = false;
		#endregion Private Properties

		#region Public Properties
		/// <summary>
		/// Gets or sets the observatory.
		/// </summary>
		/// <value>The observatory.</value>
		public Observatory Observatory
		{
			get
			{
				return m_Observatory;
			}
			set
			{
				if (m_Observatory != value)
				{
					m_Observatory = value;
					OnObservatoryChanged();
				}
			}
		}

		/// <summary>
		/// Gets or sets a value indicating whether [write non visible objects].
		/// </summary>
		/// <value>
		/// 	<c>true</c> if [write non visible objects]; otherwise, <c>false</c>.
		/// </value>
		public bool WriteNonVisibleObjects
		{
			get
			{
				return m_WriteNonVisibleObjects;
			}
			set
			{
				m_WriteNonVisibleObjects = value;
			}
		}
		#endregion Public Properties

		#region Constructors
		/// <summary>
		/// Initializes a new instance of the <see cref="ReadingsControl"/> class.
		/// </summary>
		public ReadingsControl()
		{
			InitializeComponent();

			OnObservatoryChanged();
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ReadingsControl"/> class.
		/// </summary>
		public ReadingsControl(
			IContainer container) : this()
		{
			container.Add(this);
		}

		/// <summary>
		/// Initializes a new instance of the <see cref="ReadingsControl"/> class.
		/// </summary>
		public ReadingsControl(
			IContainer container,
			Observatory observatory)
			: this(container)
		{
			Observatory = observatory;
		}
		#endregion Constructors

		/// <summary>
		/// Clears this instance.
		/// </summary>
		public void Clear()
		{
			m_RichTextBox.Clear();
		}

		/// <summary>
		/// Called when [observatory changed].
		/// </summary>
		protected virtual void OnObservatoryChanged()
		{
			m_RichTextBox.Clear();

			if (m_Observatory != null)
			{
				m_Observatory.ReadingsTaken += 
					new EventHandler<ININ.EventArgs<Reading[]>>(m_Observatory_ReadingTaken);
			}
		}

		/// <summary>
		/// Handles the ReadingTaken event of the m_Observatory control.
		/// </summary>
		/// <param name="sender">The source of the event.</param>
		/// <param name="e">The <see cref="ININ.EventArgs&lt;IUPUI.StellarResults.Reading&gt;"/> instance containing the event data.</param>
		private void m_Observatory_ReadingTaken(object sender, ININ.EventArgs<Reading[]> e)
		{
			if (!IsDisposed)
			{
				if (m_RichTextBox.InvokeRequired)
				{
					m_RichTextBox.Invoke(
						new EventHandler<ININ.EventArgs<Reading[]>>(m_Observatory_ReadingTaken),
						sender,
						e);
				}
				else
				{
					bool itemsAdded = false;
					foreach (Reading reading in e.Data)
					{
						if (m_WriteNonVisibleObjects
							|| (!m_WriteNonVisibleObjects && reading.Visible))
						{
							// Write text
							m_RichTextBox.AppendText(
								String.Format(
										Properties.Resources.ReadingText,
										reading.DateTime.AddHours(m_Observatory.UTCOffset).ToString(),
										reading.AstronomicalObject.Name,
										reading.Position.ToString(),
										reading.CurrentAltazimuth.ToString(),
										reading.NeededAltazimuth.ToString(),
										reading.Visible.ToString(),
										System.Environment.NewLine));

							itemsAdded = true;
						}
					}

					// Move to end
					if (itemsAdded && m_RichTextBox.Text.Length > 0)
					{
						m_RichTextBox.SelectionStart = m_RichTextBox.Text.Length - 1;
						m_RichTextBox.ScrollToCaret();
					}
				}
			}
		}
	}
}
